package source;

/**
 * The Unit class represents all the pieces on the field of play that can be moved.
 * These objects interact with Tile, who receives requests to pass to Unit. Unit 
 * also interacts with Map for movement and combat.
 * 
 * TODO add representation of bonuses; does not have to be in this class
 * 	i.e., owned by the PlayerStatus object instead
 * @author Sean Larson
 *
 */
public class Unit extends Entity {

	protected int mvRate;		// # of tiles unit can move in one turn
	protected int curMovement;	// # of tiles unit has left to move this turn
	
	protected UnitType uType;	// this objects enumeration value, i.e., unit type
								// ??? should this be final? can it be changed ???
								// i.e., unit upgrade changes unit type?
	protected Tile destinationTile;
	protected String orientation;
	
	/**
	 * Constructor for Unit. Takes it's UnitType from the enumeration and creates
	 * a message with all the information the superclass's constructor will need
	 * to assign to attributes
	 * @param u The UnitType enumeration value for this Unit
	 */
	public Unit(UnitType u, PlayerStatus player, Tile position) {
		super(u.eType(), new Stats(u, player, position));
		this.uType = u;
		this.mvRate = u.move();
		this.curMovement = u.move();
		this.destinationTile = null;
		this.orientation = "N";
	}
	
	/**
	 * Accessor method for this Unit's enumeration value
	 * @return UnitType enumeration value
	 */
	public UnitType getUnitType() {
		return this.uType;
	}
	
	/**
	 * Accessor method for this Unit's movement rate
	 * @return int value representing number Tiles can move in one turn
	 */
	public int getMovementRate() {
		return this.mvRate;
	}
	
	/**
	 * Accessor method for this Unit's remaining moves this turn
	 * @return int - Tiles left to move this turn
	 */
	public int getRemainingMoves() {
		return this.curMovement;
	}
	
	/** returns the energy upkeep of the Unit
	 * @return upkeep, int, representing energy units
	 */
	public int getUpkeep(){
		return uType.upkeep();
	}
	
	/**
	 * Can only be used by Army. Allows it to update its attribute according
	 * to a new Unit added to the army.
	 * @param newMove - the Unit's new movement rate (int)
	 */
	protected void setMovementRate(int newMove) {
		this.mvRate = newMove;
	}
	
	/**
	 * Sets this Unit's number of moves for the remainder of this turn. Used
	 * typically to clear a Unit's moves for this turn.
	 * @param mvs int - the value to set for Unit's current moves
	 */
	public void setRemainingMoves(int mvs) {
		this.curMovement = mvs;
	}
	
	/**
	 * Decrements this Unit's number of moves for the remainder of this turn by
	 * the value passed into the method.
	 * @param minus int - the value to decrement this Unit's current moves
	 */
	public void decrementMoves(int minus) {
		this.curMovement -= minus;
		if (this.curMovement < 0)	this.curMovement = 0;
	}
	
	public void setDestinationTile(Tile t)
	{
		destinationTile = t;
	}
	
	public Tile getDestinationTile()
	{
		return destinationTile;
	}
	
	public void setOrientation(String s)
	{
		orientation = s;
	}
	
	public String getOrientation()
	{
		return orientation;
	}
	
	public boolean newTurn() {
		this.curMovement = this.mvRate;
		return true;
	}
	
	public boolean checkDestination()
	{
		return destinationTile.equals(this.getPosition());
	}
	
	public String getPicture(){
		return uType.picture();
	}
	
	/**
	 * Unit destroys itself. It removes itself from the Players Unit Array,
	 * as well as from its Tile's Unit Array
	 */
	public boolean destroy(){
		if (getPosition().hasPlanet()) {
			Base tileBase = this.getPosition().getBase();
			if (tileBase != null) tileBase.removeHealing(this);
		}
		getPlayer().removeUnit(this);
		getPosition().removeUnit(this);
		return super.destroy();
	}
}
